package crm.base.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.AccountStatusException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert;

/**
 * 自定义验证失败处理类
 * 
 * @see org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
 * 
 * @author Zhang Qiongbiao
 *
 */
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
	
	private String defaultFailureUrl;
	private boolean forwardToDestination = false;
	private boolean allowSessionCreation = true;
	private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
	
	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
		
		if (this.defaultFailureUrl == null) {
			response.sendError(401, "Authentication Failed: " + exception.getMessage());
		} else {
			saveException(request, exception);
			exception.printStackTrace();
			
			String errorCode = "error_userNotFound";
			String username = request.getParameter("j_username");
			
			if (exception instanceof UsernameNotFoundException) {
				errorCode = "error_UsernameNotFound";
			} else if (exception instanceof AccountExpiredException) {
				errorCode = "error_AccountExpired";
			} else if (exception instanceof BadCredentialsException) {
				errorCode = "error_BadCredentials";
			} else if (exception instanceof AccountStatusException) {
				errorCode = "error_AccountStatus";
			} else if (exception instanceof CredentialsExpiredException) {
				errorCode = "error_CredentialsExpired";
			}

			String str1 = "error_";
			if (exception instanceof LockedException)
				str1 = "error_locked";
			else if (exception instanceof UsernameNotFoundException)
				str1 = "error_userNotFound";
			else if (exception instanceof AccountExpiredException)
				str1 = "error_account_expired";
			else if (exception instanceof BadCredentialsException)
				str1 = "error_password";
			else if (exception instanceof AccountStatusException)
				str1 = "error_account_disabled";
			else if (exception instanceof CredentialsExpiredException)
				str1 = "error_credentials_expired";
			System.out.println(str1);

			
//		<c:when test="${param.login_error == 'error_password'}">
//		 	alert('密码错误，请重试!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_userNotFound'}">
//			alert('该用户名不存在，请重试!');
//		</c:when>
//		<c:when test="${param.login_error == 'too_many_user_error'}">
//			alert('多处使用同一用户名登陆,请等候!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_account_expired'}">
//			alert('账号已过期，请联系管理员!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_locked'}">
//			alert('账号已锁定!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_not_worktime'}">
//			alert('非工作时间,请稍后再重试!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_account_disabled'}">
//			alert('账号未激活!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_credentials_expired'}">
//			alert('证书已失效!');
//		</c:when>
//		<c:when test="${param.login_error == 'error_not_granted_role'}">
//			alert('账号无访问权限!');
//		</c:when>

			// 数据库处理
			// ..

			
			String newFailureUrl = new StringBuffer(defaultFailureUrl).append((defaultFailureUrl.indexOf("?") < 0) ? "?" : "&").append("errorcode=").append(errorCode).toString();
			if (forwardToDestination) {
				request.getRequestDispatcher(newFailureUrl).forward(request, response);
			} else {
				redirectStrategy.sendRedirect(request, response, newFailureUrl);
			}
		}
	}

	public void setDefaultFailureUrl(String defaultFailureUrl) {
		Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultFailureUrl), "'" + defaultFailureUrl + "' is not a valid redirect URL");
		this.defaultFailureUrl = defaultFailureUrl;
	}
	
	protected final void saveException(HttpServletRequest request,AuthenticationException exception) {
		if (this.forwardToDestination) {
			request.setAttribute("SPRING_SECURITY_LAST_EXCEPTION", exception);
		} else {
			HttpSession session = request.getSession(false);

			if ((session != null) || (this.allowSessionCreation)) {
				request.getSession().setAttribute("SPRING_SECURITY_LAST_EXCEPTION", exception);
			}
		}
	}

	public void setUseForward(boolean forwardToDestination) {
		this.forwardToDestination = forwardToDestination;
	}

	public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
		this.redirectStrategy = redirectStrategy;
	}

	public void setAllowSessionCreation(boolean allowSessionCreation) {
		this.allowSessionCreation = allowSessionCreation;
	}
}
